package net.mikoo.seals.api.security;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.UnauthorizedUserException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

public class DeviceCodeTokenGranterServiceImpl implements TokenGranter {

	protected final Log logger = LogFactory.getLog(getClass());

	private AuthorizationServerTokenServices tokenServices;

	private ClientDetailsService clientDetailsService;

	private OAuth2RequestFactory requestFactory;

	private String grantType;

	static final String LOGIN_FAILD_COUNT_KEY = "login:faild:count:%s";
	protected DeviceCodeTokenGranterServiceImpl(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
			OAuth2RequestFactory requestFactory, String grantType) {
		this.clientDetailsService = clientDetailsService;
		this.grantType = grantType;
		this.tokenServices = tokenServices;
		this.requestFactory = requestFactory;
	}

	public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) {

		if (!this.grantType.equals(grantType)) {
			return null;
		}

		String clientId = tokenRequest.getClientId();
		ClientDetails client = clientDetailsService.loadClientByClientId(clientId);
		validateGrantType(grantType, client);

		Map<String, String> requestMap = tokenRequest.getRequestParameters();
		if (requestMap == null) {
			throw new UnauthorizedUserException("参数不完整");
		}
		String channel = "";
//		if (clientId.contains("ios")) {
//			channel = "IOS";
//		} else if (clientId.contains("android")) {
//			channel = "AD";
//		}
		Map<String, Object> map = new HashMap<String, Object>();
		String key = "";
//		if (requestMap.containsKey("version")) {
//			map.put("versionCode", requestMap.get("version"));
//			map.put("clientSecret", channel);
//			key = appMapper.selectAppAesKey(map);
//			if (StringUtils.isBlank(key)) {
//				throw new UnauthorizedUserException("该版本有问题");
//			}
//		}
		String consumerKey = requestMap.get("username");
		String consumerSecret = requestMap.get("password");
		String type = requestMap.get("type");
		if (StringUtils.isBlank(consumerKey)) {
			throw new UnauthorizedUserException("参数不完整");
		}
		if (StringUtils.isBlank(consumerSecret)) {
			throw new UnauthorizedUserException("参数不完整");
		}
//		UserAppDevice userAppDevice = new UserAppDevice();
//		userAppDevice.setConsumerKey(consumerKey);
//		try {
//			if (StringUtils.isBlank(key)) {
//				userAppDevice.setConsumerSecret(consumerSecret);
//			} else {
//				userAppDevice.setConsumerSecret(AESCipher.decryptAES(consumerSecret, key));
//			}
//			if (StringUtils.isBlank(type)) {
//				userAppDevice.setType("login");
//			} else {
//				userAppDevice.setType(type);
//			}
//		} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | IllegalBlockSizeException
//				| BadPaddingException | UnsupportedEncodingException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//			throw new UnauthorizedUserException("系统报错");
//		}
//		Result<User> userResult = userService.selectUserAppDevice(userAppDevice);
//		if (!userResult.isSuccess() || userResult.getModel() == null) {
//			throw new UnauthorizedUserException("该设备未绑定用户");
//		} else {
//			User user = userResult.getModel();
//			if (user.getStatus() == 1) {
//				throw new UnauthorizedUserException("您的账户已被冻结请联系客服");
//			}
//			if (user.getStatus() == 3) {
//				throw new UnauthorizedUserException("您的账户已被禁用请联系客服");
//			}
//			if (user.getStatus() == -1) {
//				throw new UnauthorizedUserException("您的账户已被删除请联系客服");
//			}
//			user.getUserLogin().setLoginTimes(user.getUserLogin().getLoginTimes() + 1);
//			user.getUserLogin().setUpLoginIp(user.getUserLogin().getLastLoginIp());
//			user.getUserLogin().setUpLoginTime(user.getUserLogin().getLastLoginTime());
//			user.getUserLogin().setLastLoginIp(request.getRemoteAddr());
//			user.getUserLogin().setLastLoginTime(new Date());
//			if (userMapper.updateUserLogin(user.getUserLogin()) == 0) {
//				throw new RuntimeException("系统出错");
//			}
//			UserLoginLog userLoginLog = new UserLoginLog();
//			userLoginLog.setUserId(user.getUserId());
//			userLoginLog.setLoginTime(new Date());
//			userLoginLog.setLoginStatus(0);
//			userLoginLog.setLoginIp(request.getRemoteAddr());
//			userLoginLog.setLoginChannel(channel);
//			userMapper.insertUserLoginLog(userLoginLog);
//		}
//		logger.debug("Getting access token for: " + clientId);

		try {
			return getAccessToken(client, tokenRequest);
		} catch (InvalidKeyException | AuthenticationException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException
				| IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RuntimeException("系统出错");
		}

	}

	protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest tokenRequest) throws InvalidKeyException, AuthenticationException,
			NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
			UnsupportedEncodingException {
		return tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest));
	}

	protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws InvalidKeyException,
			NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
			UnsupportedEncodingException {
		String clientId = tokenRequest.getClientId();
		String channel = "";
		if (clientId.contains("ios")) {
			channel = "IOS";
		} else if (clientId.contains("android")) {
			channel = "AD";
		}
		Map<String, String> requestMap = tokenRequest.getRequestParameters();
		OAuth2Request storedOAuth2Request = requestFactory.createOAuth2Request(client, tokenRequest);
//		UserAppDevice userAppDevice = new UserAppDevice();
//		userAppDevice.setConsumerKey(tokenRequest.getRequestParameters().get("username"));
		String key = "";
		if (requestMap.containsKey("version")) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("versionCode", requestMap.get("version"));
			map.put("clientSecret", channel);
//			key = appMapper.selectAppAesKey(map);
//			userAppDevice.setConsumerSecret(AESCipher.decryptAES(tokenRequest.getRequestParameters().get("password"), key));
		} else {
//			userAppDevice.setConsumerSecret(tokenRequest.getRequestParameters().get("password"));
		}
		String type = tokenRequest.getRequestParameters().get("type");
		if(StringUtils.isBlank(type)){
//			userAppDevice.setType("login");
		}else{
//			userAppDevice.setType(type);
		}
//		Result<User> userResult = userService.selectUserAppDevice(userAppDevice);
//		OauthUser oauthUser = new OauthUser();
//		oauthUser.setUsername(userResult.getModel().getPhone());
//		return new OAuth2Authentication(storedOAuth2Request, new UsernamePasswordAuthenticationToken(new CustomUserDetails(oauthUser), null));
		return new OAuth2Authentication(storedOAuth2Request, new UsernamePasswordAuthenticationToken(null, null));
	}

	protected void validateGrantType(String grantType, ClientDetails clientDetails) {
		Collection<String> authorizedGrantTypes = clientDetails.getAuthorizedGrantTypes();
		if (authorizedGrantTypes != null && !authorizedGrantTypes.isEmpty() && !authorizedGrantTypes.contains(grantType)) {
			throw new InvalidClientException("Unauthorized grant type: " + grantType);
		}
	}

	protected AuthorizationServerTokenServices getTokenServices() {
		return tokenServices;
	}

	protected OAuth2RequestFactory getRequestFactory() {
		return requestFactory;
	}

}
